#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "Person.hpp"

void student_graduate (Student *st){
	Person *pr = (Person *) st;
	Under *under = (Under *) st;

	printf ("%s graduates in %d years and finds a job in %s or goes to grad school.\n", pr->name, under->year, st->major);
}

void grad_student (Student *st){
	Person *pr = (Person *) st;
	Grad *grad = (Grad *) st;

	printf ("%s graduates with a %s and finds a job in %s.\n", pr->name, grad->degree, st->major);
}


Student* Person_downcast_Student (Person *pr){
	return (Student *)pr; //?????????????????????????????????? TODO : Return NULL if not a student
}

Under* Person_downcast_Under (Person *pr){
	return (Under *)pr; //?????????????????????????????????? TODO : Return NULL if not a under
}

Under* Student_downcast_Under (Student *st){
	return (Under *)st; //?????????????????????????????????? TODO : Return NULL if not a under
}

Grad* Person_downcast_Grad (Person *pr){
	return (Grad *)pr;
}

Professor* Person_downcast_Professor (Person *pr){
	return (Professor *)pr;
}

Grad* Student_downcast_Grad (Student *st){
	return (Grad *) st;
}


void under_work (Person *pr){
	if (pr == NULL)
		return;
	Student *st = (Student *)pr;
	printf ("%s studies %s\n",pr->name,st->major);
}

void prof_work (Person *pr){
	if (pr == NULL)
		return;
	printf ("%s teaches.\n",pr->name);
}


void prof_research(Professor *prof, const char *topic){

	Person *pr = (Person *)prof;

	printf ("%s does research in %s\n",pr->name, topic);
}

void everybody_delet(Person *pr){
	//printf ("Freed... Hussssshhhhhhhhh :) %s\n",pr->name);
	if (pr)
		free(pr);
}

Under* Under_new (const char *name, char gender, const char *major, int year){
	
	Under *new_under;

	new_under = (Under *) malloc (sizeof (Under));
	if (!new_under){
		printf ("Not enough memory\n");
		exit (1);
	}

	new_under->year = year;
	strcpy (new_under->under_st.major, major);
	strcpy (new_under->under_st.stud_per.name, name);
	new_under->under_st.stud_per.gender = gender;

	new_under->under_st.stud_per.work = under_work;
	new_under->under_st.stud_per.delet = everybody_delet;
	new_under->under_st.graduate = student_graduate;

	return new_under; // TODO: Free this after use
}

Grad* Grad_new(const char *name, char gender, const char *major, const char *degree){
	
	Grad *new_grad;
	
	new_grad = (Grad *) malloc (sizeof (Grad));
	if (!new_grad){
		printf ("Not enought memory.\n");
		exit(1);
	}

	strcpy (new_grad->degree, degree);
	strcpy (new_grad->grad_st.major, major);
	strcpy (new_grad->grad_st.stud_per.name, name);
	new_grad->grad_st.stud_per.gender = gender;

	new_grad->grad_st.stud_per.work = under_work;
	new_grad->grad_st.stud_per.delet = everybody_delet;
	new_grad->grad_st.graduate = grad_student;
	
	return new_grad; // TODO: Free this after use
}

Professor* Professor_new (const char *name, char gender, const char *office){
	
	Professor *new_prof;

	new_prof = (Professor *) malloc (sizeof (Professor));
	if (!new_prof){
		printf ("Not enough memory.\n");
		exit (1);
	}
	
	strcpy (new_prof->office, office);
	strcpy (new_prof->prof_per.name, name);
	new_prof->prof_per.gender = gender;


	new_prof->prof_per.work = prof_work;
	new_prof->prof_per.delet = everybody_delet;
	new_prof->research = prof_research;
	
	return new_prof;
}
